#pragma once

#include <string>
#include <map>
#include <list>
#include <vector>
#include <algorithm>
#include <mutex>
#include <core/strings/string_util.h>
#include "bondlib.h"
/*
[内存优化][scofined.qi]
发行人内存编码优化
原始发行人信息的结构体QBISSUERINFO的每个字段都定义的足够大
且有很多空间,且都是字符串数组成员

StringArray,如其名,是一种简单的编码,将每个成员的实
际内容紧凑的编码到一起,然后在前面放置一个每个字段
的偏移量数组访问的时候,通过成员序号来获取每个成员
的偏移量进而获取每个成员的实际字符串内容

优化数据:
StringArray优化:
主键优化:使用KeyString替换std::string,缩减一半的内存
*/
typedef std::vector<qb::base::strinfo> StringOffsets;
enum class kIssuerInfo :unsigned char{
	Institution_Code,
	Full_Name_C,
	Issuer_Type,
	SW_Sector_Code,
	SW_Subsector_Code,
	SW_2021_Sector_Code,
	SW_2021_Subsector_Code,
	Province_Code,
	Short_Name_C,
	Full_Name_E,
	Short_Name_E,
	Listed_Type,
	Actual_Controller_Name,
	Actual_Controller_Type,
	Rate,
	CBRC_Financing_Platform,
	Municipal_code,
	Issuer_tag,
	Field_Count
};

class S_BONDLIB_EXPORT StringArray{
	typedef unsigned char uchar;
	typedef unsigned short ushort;
	const ushort	m_flag : 1;
	const ushort	m_count : 15;
	//  uchar   offsets[count];	// 当falg为0的时候
	//  ushort  offsets[count]; // 当flag为1的时候
	//  紧跟着指定个数的字符串,每个都以0结尾,偏移量从此开始计算

private:
	StringArray(ushort flag, ushort count) :m_flag(flag), m_count(count){}
public:
	~StringArray(){}
	static void Destroy(StringArray* sarray);
	static StringArray* Create(const void* data, const StringOffsets& soffsets, int* pbytes = nullptr);

	int count()const{ return m_count; }
	const char* base()const;
	int offset(int index)const;
	int bytes()const;
	const char* field(int index)const;
	const char* field(kIssuerInfo index)const;
	bool check(const void* data, const StringOffsets& soffsets)const;
};


typedef struct _tag_QBISSUERINFO{
	char Institution_Code[7+1];		//发行人代码
	char Full_Name_C[80+1];			//发行机构全称
	//char Jianpin[256];				//机构名称简拼
	//char Quanpin[256];				//机构名称全拼
	char Issuer_Type[16 + 1];		//机构类型
	char SW_Sector_Code[16+1];		//一级行业代码
	char SW_Subsector_Code[16+1];	//二级行业代码
	char SW_2021_Sector_Code[16 + 1];	//2021版申万行业一级代码
	char SW_2021_Subsector_Code[16 + 1];//2021版申万行业二级代码
	char Province_Code[16+1];		//区域代码
	char Short_Name_C[80+1];		//中文简称
	char Full_Name_E[256+1];		//英文全称
	char Short_Name_E[80+1];		//英文简称
	char Listed_Type[15 + 1];		//上市公司
	char Actual_Controller_Name[128 + 1];	//实际控制人
	char Actual_Controller_Type[16 + 1];	//实际控制人类型
	char Rate[10 + 1];				//评级
	char CBRC_Financing_Platform[8];//银监会投融资平台，Y = 平台债
	char Municipal_code[16 + 1];    //市区级
}QBISSUERINFO;
typedef StringArray IssuerInfo;
#define ISSUER_FIELD(PISSUER_INFO,KISSUER_INFO) PISSUER_INFO->field((int)kIssuerInfo::KISSUER_INFO)
class S_BONDLIB_EXPORT IssuerStringOffsets : public StringOffsets{
public:
	IssuerStringOffsets();
	void Add(int off, int size){
		this->emplace_back(qb::base::strinfo{ off, size });
	}
	static IssuerStringOffsets& Get();
};

//class IssueObjectMap;
class S_BONDLIB_EXPORT CQBIssuerInfo
{
public:
	typedef qb::base::KeyString KeyString;
	typedef std::map<KeyString, IssuerInfo*> IssuerInfoMap;
	static CQBIssuerInfo& instance();
	static CQBIssuerInfo& MainUnderwriterContainer();
	static CQBIssuerInfo& ABSBondSeries();
public:
	const IssuerInfoMap& GetAllIssuerInfo()const{ return m_map; }
	IssuerInfoMap& GetAllIssuerInfo(){ return m_map; }
	const IssuerInfo* GetIssuerInfo(const std::string &id);

	bool	Clear( );
	bool	Add( const QBISSUERINFO & info );
	int		GetStateId();

	std::mutex& GetMutex(){return m_mutex;}
public:
	void DumpStatus(int mode = 0)const;
private:
	CQBIssuerInfo();
	virtual ~CQBIssuerInfo();
protected:
	IssuerInfoMap		m_map;
	std::mutex			m_mutex;
	int					m_stateid;
};
